package org.demo.test.thread.lock;

import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.Lock;

/**
 * 隐式队列
 */
public class CLHLock {

    private class Node{
        volatile boolean locked = true;
    }

    private final ThreadLocal<Node> currentNode;

    private final ThreadLocal<Node> preNode;

    private AtomicReference<Node> tail;

    public CLHLock(){
        tail = new AtomicReference<>();
        // 初始化当前的CLH节点
        currentNode = new ThreadLocal();
        // 初始化前继节点，注意此时前继节点没有存储CLHNode对象，存储的是null
        preNode = new ThreadLocal();
    }


    public void lock(){
        Node curNode = currentNode.get();
        if(curNode == null){
            curNode = new Node();
            currentNode.set(curNode);
        }
        // 如果不为空，会存在重入问题需要解决


        Node predNode = tail.getAndSet(curNode);
        if(predNode != null){
            while (predNode.locked){

            }
        }
        println("获得锁.");
    }

    public void unlock() {
        Node curNode = currentNode.get();
        if(curNode == null){
            println("未曾获取过锁.");
        }
        currentNode.remove();
        println("释放锁001.");
        curNode.locked = false;
        println("释放锁002.");
//        currentNode.remove();
    }

    private void println(String msg){
        System.out.println(Thread.currentThread().getName()+"："+msg);
    }


    public static void main(String[] args) {
        final CLHLock clhLock = new CLHLock();

        for(int i=0; i<10; i++){
            new Thread(()->{
                try {
                    clhLock.lock();
                    clhLock.println("do..........");
                    Thread.sleep(3000L);
                    clhLock.unlock();
                }catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();
        }

    }
}
